﻿Imports System.Collections.Specialized
Imports System.IO
Imports System.Globalization
Imports Microsoft.TeamFoundation.Client
Imports Microsoft.TeamFoundation.WorkItemTracking.Client
Imports System.Collections.ObjectModel
Imports System

Imports System.ComponentModel

Imports System.Xml.Serialization

Imports System.Threading
Imports QuantumBitDesigns.Core
Imports Infragistics.Windows.Ribbon
Imports Infragistics.Windows.DockManager
Imports Infragistics.Windows.DataPresenter
Imports Hinshelwood.TFSHeatITSM.Controlers.Data.Entities

Namespace Controlers

    Public Class HeatControler(Of TView As {UIElement, IHeatView(Of TView)})
        Inherits ControlerBase(Of TView)


        Private m_ContextualTagGroup As ContextualTabGroup
        Private m_MainContentPane As ContentPane
        Private m_ViewToggleButtonTool As ToggleButtonTool
        Friend m_AvailableCallLogs As ObservableList(Of CallLog)

        Public Sub New(ByVal View As TView)
            MyBase.New(View)
        End Sub

        Protected Overrides Sub Initilise()

        End Sub

        Protected Overrides Sub InitiliseObjects()
            m_AvailableApplications = New ObservableList(Of String)(View.Dispatcher)
            m_AvailableCallLogs = New ObservableList(Of CallLog)(View.Dispatcher)
        End Sub



        Protected Overrides Sub DisposeManagedObjects()
            m_AvailableApplications = Nothing
            m_AvailableCallLogs = Nothing
            m_DataContext.Dispose()
        End Sub

        Protected Overrides Sub DisposeUnmanagedObjects()

        End Sub

        Protected Overrides Sub InitiliseLoad()
            UpdateConnection_Async()
        End Sub

        Protected Overrides Sub InitiliseNavigation()
            ' Main Tabs
            Dim uxHomeTab As RibbonTabItem = GetRibbonTabItem("uxHomeTab", "Home")

            Dim uxHomeTabHeatGroup = GetRibbonGroup(uxHomeTab, "uxHomeTabHeatGroup", "Heat ITSM")
            ' Add Variants
            RibbonGroupAddVariant(uxHomeTabHeatGroup, 5, GroupVariantResizeAction.HideGalleryPreview)
            RibbonGroupAddVariant(uxHomeTabHeatGroup, 10, GroupVariantResizeAction.ReduceGalleryPreviewItems)
            RibbonGroupAddVariant(uxHomeTabHeatGroup, 20, GroupVariantResizeAction.ReduceImageAndTextNormalTools)
            RibbonGroupAddVariant(uxHomeTabHeatGroup, 30, GroupVariantResizeAction.ReduceImageAndTextLargeTools)
            RibbonGroupAddVariant(uxHomeTabHeatGroup, 40, GroupVariantResizeAction.CollapseRibbonGroup)
            uxHomeTabHeatGroup.DataContext = Me
            '

            m_ViewToggleButtonTool = New ToggleButtonTool
            m_ViewToggleButtonTool.Id = "uxHeatViewToggleButtonTool"
            m_ViewToggleButtonTool.Name = "uxHeatViewToggleButtonTool"
            m_ViewToggleButtonTool.Caption = "View"
            m_ViewToggleButtonTool.IsEnabled = False
            m_ViewToggleButtonTool.SmallImage = New BitmapImage(New Uri("\Resources\Images\HEAT16.gif", UriKind.RelativeOrAbsolute))
            m_ViewToggleButtonTool.LargeImage = New BitmapImage(New Uri("\Resources\Images\HEAT32.gif", UriKind.RelativeOrAbsolute))
            m_ViewToggleButtonTool.SetBinding(CheckBoxTool.IsEnabledProperty, "IsServicable")
            uxHomeTabHeatGroup.Items.Add(m_ViewToggleButtonTool)

            Dim resfreshButton = New ButtonTool
            resfreshButton.Id = "uxHeatViewRefreshButtonTool"
            resfreshButton.Name = "uxHeatViewToggleButtonTool"
            resfreshButton.Caption = "Refresh"
            resfreshButton.IsEnabled = False
            resfreshButton.SmallImage = New BitmapImage(New Uri("\Resources\Images\HEAT16.gif", UriKind.RelativeOrAbsolute))
            resfreshButton.LargeImage = New BitmapImage(New Uri("\Resources\Images\HEAT32.gif", UriKind.RelativeOrAbsolute))
            resfreshButton.SetBinding(CheckBoxTool.IsEnabledProperty, "IsServicable")
            uxHomeTabHeatGroup.Items.Add(resfreshButton)

            ' Contextual Tabs
            m_ContextualTagGroup = GetContextualTabGroup("HeatContextualTabGroup", "Heat ITSM")

            Dim uxDataTab As RibbonTabItem = GetRibbonTabItem(m_ContextualTagGroup, "uxHeatITSMDataTab", "Data")

            Dim uxDataTabFilterGroup = GetRibbonGroup(uxDataTab, "uxDataTabFilterGroup", "Filter")
            uxDataTabFilterGroup.DataContext = Me

            Dim FilterNotInTFS = New CheckBoxTool
            FilterNotInTFS.Id = "uxHeatFilterNotInTFS"
            FilterNotInTFS.Name = "uxHeatFilterNotInTFS"
            FilterNotInTFS.Caption = "Not In TFS"
            FilterNotInTFS.IsEnabled = False
            FilterNotInTFS.SmallImage = New BitmapImage(New Uri("\Resources\Images\HEAT16.gif", UriKind.RelativeOrAbsolute))
            FilterNotInTFS.LargeImage = New BitmapImage(New Uri("\Resources\Images\HEAT32.gif", UriKind.RelativeOrAbsolute))
            FilterNotInTFS.SetBinding(CheckBoxTool.IsCheckedProperty, "CallLogFilter_NotInTFS")
            FilterNotInTFS.SetBinding(CheckBoxTool.IsEnabledProperty, "IsServicable")
            uxDataTabFilterGroup.Items.Add(FilterNotInTFS)



            ' ContentPanes 





        End Sub

        Public Overrides Sub Reset()
            UpdateConnection_Async()
        End Sub

        Private m_IsServicable As Boolean = False

        Public Property IsServicable() As Boolean
            Get
                Return m_IsServicable
            End Get
            Private Set(ByVal value As Boolean)
                If Not value = m_IsServicable Then
                    m_IsServicable = value
                    OnPropertyChanged("IsServicable")
                End If
            End Set
        End Property

        Protected Overrides Sub RecalculateState()
            IsServicable = IsConnected And HasSelectedApplication
            If IsServicable Then
                System.Threading.ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf LoadCallLogs_Async))
            End If
        End Sub

#Region " Connection "

        Private m_ServerVersion As Integer = 0

        Public Property ServerVersion() As Integer
            Get
                Return m_ServerVersion
            End Get
            Private Set(ByVal value As Integer)
                If Not value = m_ServerVersion Then
                    m_ServerVersion = value
                    OnPropertyChanged("ServerVersion")
                End If
            End Set
        End Property


        Private m_IsConnected As Boolean = False

        Public Property IsConnected() As Boolean
            Get
                Return m_IsConnected
            End Get
            Private Set(ByVal value As Boolean)
                If Not value = m_IsConnected Then
                    m_IsConnected = value
                    OnPropertyChanged("IsConnected")
                    RecalculateState()

                End If
            End Set
        End Property

        Private m_DataContext As Data.HeatDataContext = Nothing

        Friend Property DataContext() As Data.HeatDataContext
            Get
                ' SQL Server 2000 Limitation workaround. Always generate a new DataContect. Pants, but nessesery as MultipleActiveResultSets is not supported.
                If ServerVersion < 9 And IsConnected Then
                    Return New Data.HeatDataContext(m_ConnectionString)
                End If
                Return m_DataContext
            End Get
            Private Set(ByVal value As Data.HeatDataContext)
                If Not value Is m_DataContext Then
                    m_DataContext = value
                    OnPropertyChanged("DataContext")
                    IsConnected = True
                End If
            End Set
        End Property

        Private m_ConnectionStringMask As String = "Server={0};Database={1};Trusted_Connection=yes;MultipleActiveResultSets=True;"
        Private m_ConnectionString As String = ""

        Private Sub UpdateConnection()
            Working = True
            If Not String.IsNullOrEmpty(My.Settings.HeatCatalog) And Not String.IsNullOrEmpty(My.Settings.HeatDataSource) Then
                ConnectionState = System.Data.ConnectionState.Connecting
                m_ConnectionString = String.Format(m_ConnectionStringMask, My.Settings.HeatDataSource, My.Settings.HeatCatalog)
                Try
                    Dim c As New System.Data.SqlClient.SqlConnection(m_ConnectionString)
                    AddHandler c.StateChange, AddressOf Connection_StateChange
                    AddHandler c.InfoMessage, AddressOf Connection_InfoMessage
                    c.Open()
                    If c.ServerVersion.StartsWith("08") Then
                        ServerVersion = 8
                    End If
                    ' MsgBox(Connection)
                    DataContext = New Data.HeatDataContext(c)
                    DataContext.CommandTimeout = 1000
                    DataContext.DatabaseExists()
                    UpdateApplications_Async()
                Catch ex As Exception
                    ConnectionState = System.Data.ConnectionState.Broken
                End Try
            End If
            Working = False
        End Sub

        Public Sub UpdateConnection_Async()
            Dim action As New Action(AddressOf UpdateConnection)
            action.BeginInvoke(New AsyncCallback(AddressOf UpdateApplication), Nothing)
        End Sub

        Private m_ConnectionInfoMessage As String

        Public Property ConnectionInfoMessage() As String
            Get
                Return m_ConnectionInfoMessage
            End Get
            Private Set(ByVal value As String)
                If Not value = m_ConnectionInfoMessage Then
                    m_ConnectionInfoMessage = value
                    OnPropertyChanged("ConnectionInfoMessage")
                End If
            End Set
        End Property

        Private m_ConnectionErrors As System.Data.SqlClient.SqlErrorCollection

        Public Property ConnectionErrors() As System.Data.SqlClient.SqlErrorCollection
            Get
                Return m_ConnectionErrors
            End Get
            Private Set(ByVal value As System.Data.SqlClient.SqlErrorCollection)
                If Not value Is m_ConnectionErrors Then
                    m_ConnectionErrors = value
                    OnPropertyChanged("ConnectionErrors")
                End If
            End Set
        End Property

        Private Sub Connection_InfoMessage(ByVal sender As Object, ByVal e As System.Data.SqlClient.SqlInfoMessageEventArgs)
            ConnectionInfoMessage = e.Message
            ConnectionErrors = e.Errors
        End Sub

        Private m_ConnectionState As System.Data.ConnectionState

        Public Property ConnectionState() As System.Data.ConnectionState
            Get
                Return m_ConnectionState
            End Get
            Private Set(ByVal value As System.Data.ConnectionState)
                If Not value = m_ConnectionState Then
                    m_ConnectionState = value
                    OnPropertyChanged("ConnectionState")
                End If
            End Set
        End Property

        Private Sub Connection_StateChange(ByVal sender As Object, ByVal e As System.Data.StateChangeEventArgs)
            ConnectionState = e.CurrentState
        End Sub

#End Region

#Region " Application "

        Private m_SelectedApplication As String
        Private m_HasSelectedApplication As Boolean = False
        Private m_AvailableApplications As ObservableList(Of String)

        Public Property SelectedApplication() As String
            Get
                Return m_SelectedApplication
            End Get
            Set(ByVal value As String)
                If Not m_SelectedApplication = value Then
                    m_SelectedApplication = value
                    My.Settings.SelectedHeatApplication = value
                    OnPropertyChanged("SelectedApplication")
                    HasSelectedApplication = True
                    RecalculateState()
                End If
            End Set
        End Property

        Public Property HasSelectedApplication() As Boolean
            Get
                Return m_HasSelectedApplication
            End Get
            Private Set(ByVal value As Boolean)
                If Not value = m_HasSelectedApplication Then
                    m_HasSelectedApplication = value
                    OnPropertyChanged("HasSelectedApplication")
                End If
            End Set
        End Property

        Public Sub UpdateApplication()
            If Not String.IsNullOrEmpty(My.Settings.SelectedHeatApplication) And Not m_AvailableApplications Is Nothing Then
                If m_AvailableApplications.Contains(My.Settings.SelectedHeatApplication) Then
                    SelectedApplication = My.Settings.SelectedHeatApplication
                Else
                    SelectedApplication = String.Empty
                End If
            End If
        End Sub

        Private Sub UpdateApplications_Async()
            Dim a As New Action(AddressOf UpdateApplications)
            a.BeginInvoke(Nothing, Nothing)
        End Sub

        Public ReadOnly Property AvailableApplications() As ObservableCollection(Of String)
            Get
                Return m_AvailableApplications.ObservableCollection
            End Get
        End Property

        Private Sub UpdateApplications()
            If IsConnected Then
                m_AvailableApplications.Clear()
                Dim v = From x In DataContext.CallLogs Select x.Application Distinct
                For Each s As String In v
                    m_AvailableApplications.Add(s)
                Next
                UpdateApplication()
            End If
        End Sub

#End Region

#Region " Call Logs "

        Public Sub LoadCallLogs_Async()
            LoadAvailableCallLogs_Async()
        End Sub

        Public ReadOnly Property AvailableCallLogs() As ObservableCollection(Of CallLog)
            Get
                Return m_AvailableCallLogs.ObservableCollection
            End Get
        End Property

        Public Sub LoadAvailableCallLogs_Async()
            If Not IsConnected Or Not HasSelectedApplication Then
                Return
            End If
            Dim cls = From x In DataContext.CallLogs _
                   Where x.Application = SelectedApplication _
                  And x.CallStatus <> "Closed"
            For Each c In cls
                m_AvailableCallLogs.Add(c)
            Next
            Me.State = ControlerStates.Ready
        End Sub

#End Region

        Public Function GetCallLog(ByVal callID As Integer) As Data.Entities.CallLog
            If Not IsConnected Then
                Return Nothing
            End If
            Dim v = (From x In DataContext.CallLogs Where x.CallID = callID).SingleOrDefault
            If Not v Is Nothing Then
                Return v
            End If
            Return Nothing
        End Function

        Public Function GetCallLogsTFSRef(ByVal RefNo As String) As Integer
            Dim witid As Integer = 0
            If Not RefNo Is Nothing AndAlso RefNo.StartsWith("TFS") AndAlso RefNo.Contains("\") Then
                Dim bits() As String = RefNo.Split("\")
                If bits.Length = 2 Then
                    If IsNumeric(bits(1)) Then
                        Return CInt(bits(1))
                    End If
                End If
            End If
            Return 0
        End Function

#Region " ViewableBits "

        Protected Overrides Sub PropertyHasChanged(ByVal PropertyName As String)
            Select Case PropertyName
                Case "SelectedApplication"
                    If Not m_MainContentPane Is Nothing Then m_MainContentPane.Header = String.Format("{0} Heat Calls", SelectedApplication)
            End Select
        End Sub


        Private Sub m_MainContentPane_Closed(ByVal sender As Object, ByVal e As Infragistics.Windows.DockManager.Events.PaneClosedEventArgs)
            m_ViewToggleButtonTool.IsChecked = False
        End Sub

#End Region


    End Class

End Namespace